package com.windward.vii.web.controller;

import com.windward.vii.common.Constants;
import com.windward.vii.common.JsonResult;
import com.windward.vii.common.ResultCode;
import com.windward.vii.dao.entity.AssetUserAccount;
import com.windward.vii.dao.entity.Blacklist;
import com.windward.vii.domain.banner.BannerVO;
import com.windward.vii.domain.user.*;
import com.windward.vii.service.*;
import com.windward.vii.utils.BigDecimalUtil;
import com.windward.vii.utils.StringUtils;
import com.windward.vii.utils.Utils;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping(value = "/")
public class UserController {

    private static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    UserService userService;
    @Resource
    UserTokenService userTokenService;
    @Resource
    AssetUserAccountService assetUserAccountService;
    @Resource
    BlacklistService blacklistService;
    @Resource
    AppRecordService appRecordService;
    @Resource
    AppBannerService appBannerService;

    @RequestMapping(value = "v1/api1/user/update", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult updateUserByToken(UserParam param, HttpServletRequest request,
                                     @RequestHeader(value="token") String token) {
        if(StringUtils.isBlank(param.getAvatar())) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "头像不能为空");
        }
        if(param.getNickname() == null) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "昵称不能为空，最长6个汉字，12个英文字符");
        }
        if(Utils.length(param.getNickname()) > 12) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "昵称最长6个汉字，12个英文字符");
        }
        if(param.getBirthday() == null) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "生日不能为空");
        }
        if(param.getCity() == null) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "所在地不能为空");
        }
        if(param.getSex() != null && param.getSex() != Constants.User.SEX_MEN && param.getSex() != Constants.User.SEX_WOMEN) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "性别参数错误(1:男，2:女)");
        }
        if(param.getDescription() != null && Utils.length(param.getDescription()) > 200) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "个人签名，最长100汉字，200英文字符");
        }
        AssetUserAccount userAccount = new AssetUserAccount();
        userAccount.setUid(userTokenService.getUidByToken(token));
        userAccount.setNickname(param.getNickname());
        userAccount.setAvatar(param.getAvatar());
        userAccount.setCity(param.getCity());
        userAccount.setDescription(param.getDescription());
        userAccount.setBirthday(param.getBirthday());
        userAccount.setSex(param.getSex());
        if(StringUtils.isNotEmpty(param.getCountry())) {
            userAccount.setCountry(param.getCountry());
        } else {
            userAccount.setCountry(Constants.User.COUNTRY_CHINA);
        }
        userAccount.setInfoStatus(Constants.User.INFO_STATUS_DONE);
//        userAccount.setOnlineStatus(Constants.User.ONLINE_STATUS_YES);
        userAccount.setUpdateTime(new Date());
//        logger.info("v1/api1/user/update:param={}", JSON.toJSONString(param));
        boolean result = assetUserAccountService.updateUserById(userAccount);
        return result ? JsonResult.success() : JsonResult.error();
    }

    @RequestMapping(value = "v1/api1/user/status/update", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult updateUserOnlineStatus(@RequestParam Integer status,
                                             @RequestHeader(value="token") String token) {
        if(status != Constants.User.ONLINE_STATUS_YES && status != Constants.User.ONLINE_STATUS_NO) {
            return new JsonResult(ResultCode.PARAM_ERROR_CODE, "在线状态参数错误(0:休息，9:在线)");
        }
        boolean result = assetUserAccountService.updateOnlineStatusByUid(userTokenService.getUidByToken(token), status);
        return result ? JsonResult.success() : JsonResult.error();
    }

    @RequestMapping(value = "v1/api1/user/get", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult selectUserById(Long uid,
                                     @RequestHeader(value="token") String token,
                                     @RequestHeader(value="User-Agent") String userAgent) {
        JsonResult userVOResult = userService.selectUserById(uid);
        logger.info("User-Agent:{}", userAgent);
        if(userVOResult.getCode() != ResultCode.SUCCESS_CODE) {
            return userVOResult;
        }

        UserVO userVO = (UserVO) userVOResult.getBody();
        Long loginUid = userTokenService.getUidByToken(token);
        if(!loginUid.equals(uid) && userVO != null) {
            Blacklist blacklist = blacklistService.selectByUidAndBlackUid(loginUid, uid);
            if(blacklist != null) {
                userVO.setIsBlack(true);
            }
        }

        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            if(userVO != null) {
                userVO.setPrice(0);
            }
        }
        return userVOResult;
    }

    @RequestMapping(value = "v1/api1/user/detail", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getUserDetailInfo(@RequestParam Long uid,
                                        @RequestHeader(value="token") String token,
                                        @RequestHeader(value="User-Agent") String userAgent) {
        JsonResult userVOResult = userService.selectUserById(uid);
        if(userVOResult.getCode() != ResultCode.SUCCESS_CODE) {
            return userVOResult;
        }
        UserVO userVO = (UserVO) userVOResult.getBody();
        Long loginUid = userTokenService.getUidByToken(token);
        if(!loginUid.equals(uid)) {
            Blacklist blacklist = blacklistService.selectByUidAndBlackUid(loginUid, uid);
            if(blacklist != null) {
                userVO.setIsBlack(true);
            }
        }

        AssetUserAccount assetUserAccount = assetUserAccountService.selectByUid(uid);
        if(assetUserAccount == null) {
            return JsonResult.error();
        }
        try {
            BeanUtils.copyProperties(userVO, assetUserAccount);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        UserAccountVO userAccountVO = new UserAccountVO();

        String answerRate = "0%";
        if(assetUserAccount.getAcceptTimes() > 0 && assetUserAccount.getConnectTimes() > 0) {
            BigDecimal rate = BigDecimalUtil.div(new BigDecimal(assetUserAccount.getAcceptTimes()),
                    new BigDecimal(assetUserAccount.getConnectTimes()));
            answerRate = BigDecimalUtil.round(BigDecimalUtil.mul(rate, new BigDecimal(100)), 0)+ "%";
        }
        userAccountVO.setAnswerRate(answerRate);
        try {
            BeanUtils.copyProperties(userAccountVO, assetUserAccount);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        userAccountVO.setAvailableRechargeCoin(assetUserAccount.getAvailableReceiveCoin() + assetUserAccount.getAvailableRechargeCoin());
        UserDetailVO userDetailVO = new UserDetailVO();
        userDetailVO.setUser(userVO);
        userDetailVO.setAccount(userAccountVO);


        logger.info("User-Agent:{}", userAgent);
        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            userDetailVO.getUser().setPrice(0);
        }

        JsonResult jsonResult = JsonResult.success();
        jsonResult.setBody(userDetailVO);
        return jsonResult;
    }
    
    @RequestMapping(value = "v1/api0/user/list/newest", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getNewestUserList(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                        @RequestHeader(value="User-Agent") String userAgent) {
        logger.info("pageNum={}", pageNum);
        logger.info("pageSize={}", pageSize);
        pageNum = pageNum > 0 ? pageNum : 1;
        List<UserVO> userList = userService.getNewestUserList(pageNum, pageSize);

        logger.info("User-Agent:{}", userAgent);
        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            if(userList != null && userList.size() > 0) {
                for(UserVO userVO : userList) {
                    userVO.setPrice(0);
                }
            }
        }

        return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, userList);
    }

    @RequestMapping(value = "v1/api0/user/list/recommend", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getRecommendUserList(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                           @RequestHeader(value="User-Agent") String userAgent) {
        logger.info("pageNum={}", pageNum);
        logger.info("pageSize={}", pageSize);
        pageNum = pageNum > 0 ? pageNum : 1;
        List<UserVO> list = userService.getRecommendUserList(pageNum, pageSize);
        logger.info("User-Agent:{}", userAgent);
        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            if(list != null && list.size() > 0) {
                for(UserVO userVO : list) {
                    userVO.setPrice(0);
                }
            }
        }

        return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, list);
    }

    @RequestMapping(value = "v2/api0/user/list/newest", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getNewestUserListV2(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                          @RequestHeader(value="User-Agent") String userAgent) {
        logger.info("pageNum={}", pageNum);
        logger.info("pageSize={}", pageSize);
        pageNum = pageNum > 0 ? pageNum : 1;
        List<UserVO> userList = userService.getNewestUserList(pageNum, pageSize);

        logger.info("User-Agent:{}", userAgent);
        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            if(userList != null && userList.size() > 0) {
                for(UserVO userVO : userList) {
                    userVO.setPrice(0);
                }
            }
        }

        // 最新banner
        UserBannerVO userBannerVO = new UserBannerVO();
        userBannerVO.setUsers(userList);
        if(pageNum <= 1) {
            userBannerVO.setBanners(appBannerService.getNewestBanner());
        } else {
            userBannerVO.setBanners(new ArrayList<>());
        }

        return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, userBannerVO);
    }

    @RequestMapping(value = "v2/api0/user/list/recommend", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getRecommendUserListV2(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                           @RequestHeader(value="User-Agent") String userAgent) {
        logger.info("pageNum={}", pageNum);
        logger.info("pageSize={}", pageSize);
        pageNum = pageNum > 0 ? pageNum : 1;
        List<UserVO> list = userService.getRecommendUserList(pageNum, pageSize);
        logger.info("User-Agent:{}", userAgent);
        boolean isInReviewVersion = appRecordService.checkIsInReview(userAgent);
        if(isInReviewVersion) {
            if(list != null && list.size() > 0) {
                for(UserVO userVO : list) {
                    userVO.setPrice(0);
                }
            }
        }

        // 推荐banner
        UserBannerVO userBannerVO = new UserBannerVO();
        userBannerVO.setUsers(list);
        if(pageNum <= 1) {
            userBannerVO.setBanners(appBannerService.getRecommendBanner());
        } else {
            userBannerVO.setBanners(new ArrayList<>());
        }

        return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, userBannerVO);
    }

    @RequestMapping(value = "v1/api0/user/search", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult searchUser(SearchParam searchParam, HttpServletRequest request, @RequestHeader(value="User-Agent") String userAgent) {
        logger.info("User-Agent:{}", userAgent);
        String token = request.getHeader("token");
        if(token != null) {
            Long uid = userTokenService.getUidByToken(token);
            if(uid != null) {
                searchParam.setLoginUid(uid) ;
            }
        }
        if(searchParam.getPageNum() != null) {
            logger.info("pageNum={}", searchParam.getPageNum());
            logger.info("pageSize={}", searchParam.getPageSize());
            if(searchParam.getPageNum() == null || searchParam.getPageNum() <= 0) {
                searchParam.setPageNum(1);
            }
        }
        List<UserVO> list = userService.searchUser(searchParam);
        return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, list);
    }

    @RequestMapping(value = "v1/api1/device/token/bind", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult bindDeviceToken(@RequestParam String deviceId,
                                      @RequestParam String deviceToken,
                                      @RequestHeader(value="token") String token) {
        Long uid = userTokenService.getUidByToken(token);
        return userService.bindDeviceToken(uid, deviceId, deviceToken);
    }
}
